use std::future::Future;
use std::io::stdout;

use color_eyre::Result;
use colored::Colorize;
use crossterm::event::{self, Event, KeyCode, KeyEvent, MouseEvent, MouseEventKind};
use crossterm::execute;
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
use ratatui::style::{Color, Style, Stylize};
use ratatui::text::{Line, Masked, Span};
use ratatui::widgets::{Paragraph, Wrap};
use ratatui::{DefaultTerminal, Frame};
use rig::agent::Agent;
use rig::client::completion::CompletionModelHandle;
use rig::message::Message;

pub trait HandlerInput<'a> {
    async fn handle_input(&mut self, input: &String) -> String;
}

pub async fn run_interact<'a>(
    callback: &'a mut impl HandlerInput<'a>,
) -> Result<(), Box<dyn std::error::Error>> {
    let terminal = ratatui::init();
    let result = run(terminal, callback).await;
    ratatui::restore();
    result
}

async fn run<'a>(
    mut terminal: DefaultTerminal,
    callbacker: &'a mut impl HandlerInput<'a>,
) -> Result<(), Box<dyn std::error::Error>> {
    let mut input = String::new();
    let mut lines: Vec<Line> = create_lines();
    let mut scroll_y: i32 = 0;

    let mut stdout = stdout();
    execute!(stdout, event::EnableMouseCapture {});

    loop {
        terminal.draw(|frame| {
            let vertical =
                Layout::vertical([Constraint::Fill(1), Constraint::Length(2)]).spacing(1);
            let [main, buttom] = vertical.areas(frame.area());

            // 文本列表
            let chat_paragraph = Paragraph::new(lines.clone())
                .style(Color::White)
                .scroll((scroll_y.max(0) as u16, 0))
                .wrap(Wrap { trim: true });
            frame.render_widget(chat_paragraph, main);

            // 底部输入框
            let buttom_paragraph = Paragraph::new(format!("{} {}{}", ">>>", input, "|".blink()))
                .style(Color::White)
                .alignment(Alignment::Left);
            frame.render_widget(buttom_paragraph, buttom);
        })?;

        let lis_event: Event = event::read()?;
        match lis_event {
            Event::Key(key_event) => {
                if key_event.code == KeyCode::Esc {
                    execute!(stdout, event::DisableMouseCapture {});
                    break;
                }
                if key_event.code == KeyCode::Backspace {
                    input.pop();
                } else if key_event.code == KeyCode::Enter {
                    if input != "" {
                        // 输出问题
                        lines.push(
                            Span::styled(input.clone(), Style::new().yellow().italic()).into(),
                        );

                        let result: String = callbacker.handle_input(&input).await;
                        input = String::new();

                        // 处理多行
                        for line in result.split("\n") {
                            lines.push(line.to_string().into());
                        }
                    }
                } else {
                    if let Some(ch) = key_event.code.as_char() {
                        input.push(ch);
                    }
                }
            }
            Event::Mouse(mouse_event) => {
                match mouse_event.kind {
                    MouseEventKind::ScrollUp => {
                        scroll_y = (scroll_y - 1).max(0);
                    }
                    MouseEventKind::ScrollDown => {
                        scroll_y = (scroll_y + 1).min(lines.len() as i32 - 1);
                    }
                    _ => {}
                };
            }
            _ => {}
        }
    }
    Ok(())
}

fn render(frame: &mut Frame) {
    let vertical = Layout::vertical([Constraint::Fill(1), Constraint::Length(1)]).spacing(1);
    let [main, buttom] = vertical.areas(frame.area());

    // 文本列表
    let chat_paragraph = Paragraph::new(create_lines())
        .style(Color::White)
        .scroll((0, 0))
        .wrap(Wrap { trim: true });
    frame.render_widget(chat_paragraph, main);

    // 底部输入框
    let text = "Centered text\nwith multiple lines.\nCheck out the recipe!";
    let buttom_paragraph = Paragraph::new(text)
        .style(Color::White)
        .alignment(Alignment::Center);
    frame.render_widget(buttom_paragraph, buttom);
}

fn create_lines() -> Vec<Line<'static>> {
    let short_line = "Slice, layer, and bake the vegetables 11111111. ";
    let long_line = short_line.repeat(6);
    vec![
    // 作参考
        // "Recipe: Ratatouille".into(),
        // "Ingredients:".bold().into(),
        // Line::from_iter([
        //     "Bell Peppers".into(),
        //     ", Eggplant".italic(),
        //     ", Tomatoes".bold(),
        //     ", Onion".into(),
        // ]),
        // Line::from_iter([
        //     "Secret Ingredient: ".underlined(),
        //     Span::styled(Masked::new("herbs de Provence", '*'), Color::Red),
        // ]),
        // "Instructions:".bold().yellow().into(),
        // long_line.green().italic().into(),
    ]
}

#[tokio::test]
async fn test() -> Result<()> {
    color_eyre::install()?;
    let mut test_struct = TestStruct;
    run_interact(&mut test_struct).await;
    Ok(())
}
struct TestStruct;
impl<'a> HandlerInput<'a> for TestStruct {
    async fn handle_input(&mut self, input: &String) -> String {
        let input = input.clone();
        format!("echo {}", input)
    }
}
